package com.example.rbacmanage.config;

import cn.hutool.json.JSONObject;
import com.example.rbacmanage.common.Constant;
import com.example.rbacmanage.entity.AppUser;
import com.example.rbacmanage.entity.Chat;
import com.example.rbacmanage.entity.ChatJoin;
import com.example.rbacmanage.entity.User;
import com.example.rbacmanage.mapper.AppUserMapper;
import com.example.rbacmanage.mapper.ChatJoinMapper;
import com.example.rbacmanage.mapper.ChatMapper;
import com.example.rbacmanage.mapper.UserMapper;
import com.example.rbacmanage.util.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author CoderJia
 * @create 2024/12/15 下午 08:21
 * @Description
 **/
@Component
@Slf4j
public class WebSocketCustomHandler extends TextWebSocketHandler {

    // 用于存储WebSocket会话
    private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AppUserMapper appUserMapper;
    @Autowired
    private ChatMapper chatMapper;
    @Autowired
    private ChatJoinMapper chatJoinMapper;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String sessionId = session.getId();
        String key = getKey(session);
        if (key != null){
            sessions.put(key, session);
        }
        log.info("WebSocket连接建立成功：{}", sessionId);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        log.info("收到消息：{}", payload);
        //将收到的消息发送给对方
        if (payload.contains("heart")){
            session.sendMessage(new TextMessage("ok"));
        }else{
            JSONObject jsonObject = new JSONObject(payload);
            String key = getKey(session);
            if(jsonObject.containsKey("customerMsg")){
                String msg = jsonObject.getStr("customerMsg");
                Long shopId = jsonObject.getLong("shopId");
                Long goodsId = jsonObject.getLong("goodsId");
                Long orderId = jsonObject.getLong("orderId");
                String msgType = jsonObject.getStr("msgType");
                String chatObj=jsonObject.getStr("chatObj");

                List<Long> userIds = new ArrayList<>();


                //获取当前接入的该店铺系统用户，如果没有，就发给所有该店铺下的客服
                String minappUserId=key.substring(Constant.MINAPP_USER.length());
                ChatJoin join = new ChatJoin();
                join.setMiappUserId(Long.valueOf(minappUserId));
                List<ChatJoin> chatJoins = chatJoinMapper.list(join);
                List<Long> joinedSystemIds = chatJoins.stream().map(ChatJoin::getJoinedSystemUserId).toList();
                if (!joinedSystemIds.isEmpty()){
                    User user = new User();
//                    user.setIds(joinedSystemIds);
                    List<User> usersJoined = userMapper.list(user);
                    for (User u : usersJoined){
                       /* if (shopId.equals(u.getShopId())){
                            userIds.add(u.getId());
                        }*/
                    }
                }
                if (userIds.isEmpty()){
                    User query = new User();
//                    query.setShopId(shopId);
                    List<User> users = userMapper.list(query);
                    userIds=users.stream().map(User::getId).toList();
                }
                if (!userIds.isEmpty()){
                    Chat sendChat = null;
                    for (Long userId:userIds){
                        //保存数据库
                        Chat chat = new Chat();
                        chat.setChatObj(chatObj);
                        chat.setCreateTime(new Date());
                        chat.setSystemUserId(userId);
                        chat.setMinappUserId(Long.valueOf(minappUserId));
                        chat.setMsg(msg);
                        chat.setSendRole(1);
                        chat.setRead("0");
                        chat.setMsgType(msgType);
                        chat.setGoodsId(goodsId);
                        chat.setOrderId(orderId);
                        chat.setShopId(shopId);
                        chatMapper.insert(chat);
                        sendChat=chat;
                        WebSocketSession session1 = sessions.get(Constant.SYSTEM_USER +userId);
                        if (session1 != null && session1.isOpen()){
                            session1.sendMessage(new TextMessage(com.alibaba.fastjson.JSONObject.toJSONString(chat)));
                        }
                    }
                    if (sendChat != null){
                        session.sendMessage(new TextMessage(com.alibaba.fastjson.JSONObject.toJSONString(sendChat)));
                    }
                }
            }else if (jsonObject.containsKey("customerServiceMsg")){
                //customerServiceMsg客服消息发送给客户
                String msg = jsonObject.getStr("customerServiceMsg");
                String userId = jsonObject.getStr("userId");
                String msgType = jsonObject.getStr("msgType");
                //保存数据库
                Chat chat = new Chat();
                chat.setCreateTime(new Date());
                String systemUserId=key.substring(Constant.SYSTEM_USER.length());
                User user = userMapper.queryOneById(Long.valueOf(systemUserId));
                if (user != null){
//                    chat.setShopId(user.getShopId());
                }
                chat.setSystemUserId(Long.valueOf(systemUserId));
                chat.setMinappUserId(Long.valueOf(userId));
                chat.setMsg(msg);
                chat.setSendRole(0);
                chat.setRead("0");
                chat.setMsgType(msgType);
                chatMapper.insert(chat);
                if (sessions.containsKey(Constant.MINAPP_USER+userId)){
                    WebSocketSession session1 = sessions.get(Constant.MINAPP_USER+userId);
                    session1.sendMessage(new TextMessage(com.alibaba.fastjson.JSONObject.toJSONString(chat)));
                    session.sendMessage(new TextMessage(com.alibaba.fastjson.JSONObject.toJSONString(chat)));
                }
            }
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String sessionId = session.getId();
        String key = getKey(session);
        if (key != null){
            sessions.remove(key);
        }
        log.info("WebSocket连接关闭：{}", sessionId);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.error("WebSocket传输错误", exception);
    }

    // 广播消息给所有连接的客户端
    public void broadcastMessage(String message) {
        sessions.values().forEach(session -> {
            try {
                session.sendMessage(new TextMessage(message));
            } catch (IOException e) {
                log.error("广播消息失败", e);
            }
        });
    }

    public String getKey(WebSocketSession session){
        List<String> tokens = session.getHandshakeHeaders().get("Sec-WebSocket-Protocol");
        if (CollectionUtils.isNotEmpty(tokens)) {
            String token = tokens.get(0);
            if (token.matches("-?\\d+(\\.\\d+)?")){
                //手机号
                return token;
            }else{
                //token值
                String username = JwtTokenUtil.getUsernameFromToken(token);
                User user = userMapper.queryOneByUsername(username);
                if (user != null){
                    return Constant.SYSTEM_USER +user.getId();
                }else{
                    AppUser appUser = appUserMapper.queryOneById(Long.valueOf(username));
                    if (appUser != null){
                        return  Constant.MINAPP_USER +appUser.getId();
                    }
                }
            }
        }
        return null;
    }
}
